package com.lance.shiro.service;

import com.lance.shiro.config.PropertySaleStatus;
import com.lance.shiro.entity.IProperty;
import com.lance.shiro.entity.IPropertyList;
import com.lance.shiro.entity.ISalesNotification;
import com.lance.shiro.entity.IUser;
import com.lance.shiro.mapper.CommonMapper;
import com.lance.shiro.mapper.PropertyMapper;
import com.lance.shiro.mapper.SalesNotificationMapper;
import com.lance.shiro.mapper.UserMapper;
import com.lance.shiro.utils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Map;

import static com.lance.shiro.config.ConstantVariable.BELONG_TO_CATEGORY_PROPERTY_BANK_CARD_PICTURE;
import static com.lance.shiro.config.ConstantVariable.BELONG_TO_CATEGORY_SALES_NOTIFICATION_PROPERTY_BANK_CARD_PICTURE;

@Service
@Transactional
public class SalesNotificationServiceImpl implements SalesNotificationService {
    public Logger log = LogManager.getLogger(getClass());
    @Autowired
    private CommonService commonService;

    @Autowired
    private UMailService uMailService;

    @Autowired
    private SalesNotificationMapper salesNotificationMapper;

    @Autowired
    private PropertyMapper propertyMapper;

    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private UserMapper userMapper;


    @Value("${mail.manager.username}")
    private String mailManager;

    @Override
    public ArrayList<Map> findAll() {
        ArrayList<ISalesNotification> list = salesNotificationMapper.findAll();
        return setAttachmentForList(list);
    }

    @Override
    public Map get(int id) {
        ISalesNotification iSalesNotification = salesNotificationMapper.get(id);
        if (null != iSalesNotification) {
            return setAttachment(iSalesNotification);
        } else {
            return ConvertUtils.beanToMap(iSalesNotification);
        }
    }

    @Override
    public Map saveAdd(ISalesNotification entity) throws Exception {
        ISalesNotification iSalesNotification = salesNotificationMapper.findByPropertyIdAgentId(entity.getPropertyId(), entity.getAgentId());
        if (null != iSalesNotification) {
            throw new Exception("The record exists!");
        } else {
            salesNotificationMapper.saveAdd(entity);
            ISalesNotification temp = salesNotificationMapper.get(entity.getId());
            sendNotifySaleEmailToReferel(temp); //send email once notification created
            return setAttachment(temp);
        }
    }

    @Override
    public Map saveUpdate(ISalesNotification entity) throws Exception {
        ISalesNotification iSalesNotification = salesNotificationMapper.findByPropertyIdAgentIdUpdate(entity.getId(), entity.getPropertyId(), entity.getAgentId());
        if (null != iSalesNotification) {
            throw new Exception("Not Update ,The Recode has been!");
        } else {
            ISalesNotification temp = salesNotificationMapper.get(entity.getId());
            salesNotificationMapper.saveUpdate(entity);
            sendNotifySaleEmailToReferel(temp); //send email once notification created
            // 判断是否发邮件
            if (null == temp.getSaleNotificationContent()) {
                if (null != entity.getSaleNotificationContent()) {
                    sendNotifySaleMail(temp.getProperty(), temp.getAgent(), temp.getPropertyList(), entity.getSaleNotificationContent());
                }
            }
            return setAttachment(temp);
        }
    }

    private void sendNotifySaleEmailToReferel(ISalesNotification notification) throws Exception {
        int agentID = notification.getAgentId();
        IUser agent = userMapper.get(agentID);
        String referID = agent.getReferID();
        IUser referer = userMapper.findByAttrAndStatus(String.format("code='%s'",referID));
        int propertyID = notification.getPropertyId();
        IProperty property = propertyMapper.get(propertyID);
        String subject =  String.format("%s has submit a sale notification for [%s]: [%s] with price: [%s]",
                agent.getFirstName(),property.getPropertyList().getName(), property.getLot(),property.getSellingPrice());
        String body = "<div>Content:"+subject+"</div>";

        uMailService.sendManagerMail(referer.getEmail(), subject, body);

    }

    private void sendNotifySaleMail(IProperty iProperty, IUser agent, IPropertyList propertyList, String saleNotificationContent) throws Exception {
        String to = userMapper.getAdminEmail();
        if (to != null && !to.equals("")) {
            String subject = String.format("Project:[%s], Lot:[%s]  has received a deposit", propertyList.getName(), iProperty.getLot());
            String body = "<div>Agent: " + agent.getCode() + " " +
                    agent.getFirstName() + " " + agent.getLastName() +
                    " has submitted a property  deposit request for " + String.format("Project:[%s], Lot:[%s]", propertyList.getName(), iProperty.getLot()) +
                    " at time: " + iProperty.getUpdateTime() + "</div>";
            body += "<div>Sales Notes: " + saleNotificationContent + "</div>";
            body += "<div><a href=\"https://ipanproperty.com\" target='_blank'>https://ipanproperty.com</a></div>";
            uMailService.sendManagerMail(to, subject, body);
        }
    }

    @Override
    public Map reject(int id, Map<String, String> reqMap) {
        String comments = "";
        if (null != reqMap && StringUtils.isNotBlank(reqMap.get("comments"))) {
            comments = reqMap.get("comments");
        }
        ISalesNotification iSalesNotification = salesNotificationMapper.get(id);
        if (null != iSalesNotification) {
            // 1.send email (comments compose to email)
            IProperty property = propertyMapper.get(iSalesNotification.getPropertyId());
            property.setSale_status(PropertySaleStatus.FOR_SALE);
            property.setAgentId(0);
            property.setSale_note("");
            sendRejectMail(iSalesNotification.getAgent(), iSalesNotification.getProperty(), iSalesNotification.getPropertyList(), comments);
            // 2.delete notification record (by id)
            salesNotificationMapper.delete(id);
            // 3.删除附件
            deleteAttachment(id);
        }
        return setAttachment(iSalesNotification);
    }

    @Override
    public Map accept(int id, Map<String, String> reqMap) {
        String comments = "";
        if (null != reqMap && StringUtils.isNotBlank(reqMap.get("comments"))) {
            comments = reqMap.get("comments");
        }
        ISalesNotification iSalesNotification = salesNotificationMapper.get(id);
        if (null != iSalesNotification) {
            // 1.send email (comments compose to email)
            sendAcceptMail(iSalesNotification.getAgent(), iSalesNotification.getProperty(), iSalesNotification.getPropertyList(), comments);

            //给上级发送邮件告知
            sendReferMail(iSalesNotification.getAgent(), iSalesNotification.getProperty(), iSalesNotification.getPropertyList());

            // 2.更新property
            IProperty property = propertyMapper.get(iSalesNotification.getPropertyId());
            property.setSale_status(PropertySaleStatus.DEPOSIT_TAKEN);
            property.setAgentId(iSalesNotification.getAgentId());
            property.setSale_note(iSalesNotification.getSaleNotificationContent());
            property.setOwnerId(iSalesNotification.getCustomerId());
            property.setSolicitorId(iSalesNotification.getSolicitorId());
            propertyMapper.update(property);
            // 3.更新更新图片
            commonMapper.updateAttachmentProperty(property.getId(), BELONG_TO_CATEGORY_PROPERTY_BANK_CARD_PICTURE, id, BELONG_TO_CATEGORY_SALES_NOTIFICATION_PROPERTY_BANK_CARD_PICTURE);
            // 4.删除记录
            salesNotificationMapper.delete(id);

            // 4.delete all notification records (与该property相关的记录全删除)
//            ArrayList<ISalesNotification> salesNotificationArrayList = salesNotificationMapper.findAllByPropertyId(iSalesNotification.getPropertyId());
//            if (null != salesNotificationArrayList && salesNotificationArrayList.size() > 0) {
//                for (ISalesNotification temp : salesNotificationArrayList) {
//                    if (id != temp.getId()) {
//                        ISalesNotification sendTemp = salesNotificationMapper.get(temp.getId());
//                        sendAcceptedMail(sendTemp.getAgent(), sendTemp.getProperty(), sendTemp.getPropertyList());
//                        deleteAttachment(temp.getId());
//                    }
//                    salesNotificationMapper.delete(temp.getId());
//                }
//            }
        }
        return setAttachment(iSalesNotification);
    }

    @Override
    public ArrayList<Map> findAllByPropertyId(int propertyId) {
        ArrayList<ISalesNotification> salesNotificationArrayList = salesNotificationMapper.findAllByPropertyId(propertyId);
        return setAttachmentForList(salesNotificationArrayList);
    }

    @Override
    public void deleteAllByIds(ArrayList<Integer> ids) {
        for (int i = 0, size = ids.size(); i < size; i++) {
            salesNotificationMapper.delete(ids.get(i));
            deleteAttachment(ids.get(i));
        }
    }

    private void sendRejectMail(IUser user, IProperty property, IPropertyList propertyList, String comments) {
        try {
            String subject = "Your property sale request has been rejected";
            String body = "<div>Dear " + user.getFirstName() + " " + user.getLastName() + ", </div>";
            body += "<div>Your property sale request for " + propertyList.getName() + " Lot:" + property.getLot() + " with price: </div>";
            body += "<div>  " + property.getSellingPrice() + " has been rejected. </div>";
            body += "<div>" + comments + " Thank you. </div>";
            Map<String, String> ret = uMailService.sendManagerMail(user.getPrivateEmail(), subject, body);
        } catch (Exception ex) {
            log.error(ex);
        }
    }

    private void sendAcceptMail(IUser user, IProperty property, IPropertyList propertyList, String comments) {
        try {
            String subject = "Your property sale request has been accepted";
            String body = "<div>Dear " + user.getFirstName() + " " + user.getLastName() + " </div>";
            body += "<div>your property sale request for " + propertyList.getName() + " " + property.getLot() + " with price: </div>";
            body += "<div>  " + property.getSellingPrice() + "  has been accepted. </div>";
            body += "<div>" + comments + " Thank you. iPAN system </div>";
            Map<String, String> ret = uMailService.sendManagerMail(user.getPrivateEmail(), subject, body);
        } catch (Exception ex) {
            log.error(ex);
        }
    }

    /**
     * 用户推荐的上级在下级的房子卖掉（Settled）之后需要收到邮件告知他的下级已经卖了一套房子
     *
     * @param user
     * @param property
     * @param propertyList
     */
    private void sendReferMail(IUser user, IProperty property, IPropertyList propertyList) {

        try {
            String subject = "Your down-line: " + user.getCode() + " " + user.getFirstName() + " " + user.getLastName() + " " +
                    "has submitted an approved sales notification for property: "
                    + propertyList.getName() + ", Lot: " + property.getLot() + "";

            String referID = user.getReferID();
            IUser referer = userMapper.findByAttrAndStatus(String.format("code='%s'", referID));

            String body = "<div>Hi " + referer.getFirstName() + " " + referer.getLastName() + " ,</div>";
            body += "<div></div>";
            body += "<div>Congratulations!</div>";
            body += "<div>" + subject + " with listed price: " + property.getSellingPrice() + "</div>";
            body += "<div></div>";
            body += "<div>Note: The actual sell price might be different from listed price.</div>";

            Map<String, String> ret = uMailService.sendManagerMail(referer.getPrivateEmail(), subject, body);
        } catch (Exception ex) {
            log.error(ex);
        }
    }


//    private void sendAcceptedMail(IUser user, IProperty property, IPropertyList propertyList) {
//        try {
//            String subject = "your application for " + propertyList.getName() + " " + property.getLot() + " has been taken by other member.";
//            String body = "<div>Dear " + user.getFirstName() + " " + user.getLastName() + " </div>";
//            body += "<div>your property sale request for " + propertyList.getName() + " " + property.getLot() + " with price: </div>";
//            body += "<div>  " + property.getSellingPrice() + "  has been taken by other member. </div>";
//            body += "<div> Thank you. iPAN system </div>";
//            Map<String, String> ret = uMailService.sendManagerMail(user.getPrivateEmail(), subject, body);
//        } catch (Exception ex) {
//        }
//    }

    private ArrayList<Map> setAttachmentForList(ArrayList<ISalesNotification> list) {
        ArrayList<Map> aProperty = new ArrayList<>();
        for (int i = 0, size = list.size(); i < size; i++) {
            Map maProperty = setAttachment(list.get(i));
            aProperty.add(maProperty);
        }
        return aProperty;
    }

    private Map setAttachment(ISalesNotification entity) {
        Map mEntity = ConvertUtils.beanToMap(entity);
        String id = String.valueOf(entity.getId());
        mEntity.put(BELONG_TO_CATEGORY_SALES_NOTIFICATION_PROPERTY_BANK_CARD_PICTURE, commonService.findListAttachmentByBelong(id, BELONG_TO_CATEGORY_SALES_NOTIFICATION_PROPERTY_BANK_CARD_PICTURE));
        return mEntity;
    }

    private void deleteAttachment(Integer id) {
        String sid = String.valueOf(id);
        commonService.deleteListAttachmentByBelong(sid, BELONG_TO_CATEGORY_SALES_NOTIFICATION_PROPERTY_BANK_CARD_PICTURE);
    }

}